package com.yupi.mianshiya.job.once;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.mianshiya.esdao.QuestionEsDao;
import com.yupi.mianshiya.model.dto.question.QuestionEsDTO;
import com.yupi.mianshiya.model.entity.Question;
import com.yupi.mianshiya.service.QuestionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 全量同步题目到 es
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://yupi.icu">编程导航知识星球</a>
 */
// todo 取消注释开启任务
//@Component
@Slf4j
public class FullSyncQuestionToEs implements CommandLineRunner {

    @Resource
    private QuestionService questionService;

    @Resource
    private QuestionEsDao questionEsDao;
    @Resource
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Override
    public void run(String... args) {

        //大数据量 流式处理  线程池
        // 全量获取题目（数据量不大的情况下使用）
        List<Question> questionList = questionService.list();
        if (CollUtil.isEmpty(questionList)) {
            return;
        }
        // 转为 ES 实体类
        List<QuestionEsDTO> questionEsDTOList = questionList.stream()
                .map(QuestionEsDTO::objToDto)
                .collect(Collectors.toList());
        // 分页批量插入到 ES
        final int pageSize = 500;
        int total = questionEsDTOList.size();

//        ExecutorService executor = Executors.newFixedThreadPool(10); // 创建线程池
//        int totalPages = (int) Math.ceil((double) total / pageSize);
//
//        for (int page = 0; page < totalPages; page++) {
//            final int currentPage = page;
//
//            executor.submit(() -> {
//                // 分页查询数据
//                Page<Question> questionPage = questionService.page(new Page<>(currentPage, pageSize));
//                List<Question> questionList = questionPage.getRecords();
//
//                if (!CollUtil.isEmpty(questionList)) {
//                    List<QuestionEsDTO> questionEsDTOList = questionList.stream()
//                            .map(QuestionEsDTO::objToDto)
//                            .collect(Collectors.toList());
//
//                    List<IndexQuery> queries = questionEsDTOList.stream()
//                            .map(question -> new IndexQueryBuilder()
//                                    .withId(String.valueOf(question.getId()))
//                                    .withObject(question)
//                                    .build())
//                            .collect(Collectors.toList());
//
//                    elasticsearchTemplate.bulkIndex(queries, BulkOptions.defaultOptions().getClass());
//                    log.info("Synced page {}", currentPage);
//                }
//            });
//        }
        // 等待所有任务完成
//        executor.shutdown();
//        executor.awaitTermination(1, TimeUnit.HOURS);
        log.info("FullSyncQuestionToEs start, total {}", total);
        for (int i = 0; i < total; i += pageSize) {
            // 注意同步的数据下标不能超过总数据量
            int end = Math.min(i + pageSize, total);
            log.info("sync from {} to {}", i, end);
            questionEsDao.saveAll(questionEsDTOList.subList(i, end));
            // 构建批量插入请求
//            List<IndexQuery> queries = questionEsDTOList.subList(i,end).stream()
//                    .map(question -> new IndexQueryBuilder()
//                            .withId(String.valueOf(question.getId())) // 使用主键作为文档 ID
//                            .withObject(question)
//                            .build())
//                    .collect(Collectors.toList());
//
//            // 批量插入数据到 ES
//            elasticsearchTemplate.bulkIndex(queries, BulkOptions.defaultOptions().getClass());
        }

        log.info("FullSyncQuestionToEs end, total {}", total);
    }
}
